package com.share.tools.security;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;


import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Objects;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * @author caifan
 * @desc AES加密
 * @date 2020/9/21
 */
public class AESUtils {
    private static final String AES_NAME = "AES";

    private static final String ALGORITHM = "AES/CBC/PKCS7Padding";

    static {
    	if (Objects.isNull(Security.getProvider(BouncyCastleProvider.PROVIDER_NAME))) {
    		Security.addProvider(new BouncyCastleProvider());
    	}
    }

    /**
     * 加密
     * @param content 内容
     * @param key 密码
     * @return
     */
    public static String encrypt(String content, String key) {
        try {
            Cipher cipher = initCipher(key, Cipher.ENCRYPT_MODE);
            byte[] result = cipher.doFinal(content.getBytes(UTF_8));
            return Base64.encodeBase64String(result);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解密
     * @param content 密文
     * @param key 密码
     * @return
     */
    public static String decrypt(String content, String key) {
        try {
            Cipher cipher = initCipher(key, Cipher.DECRYPT_MODE);
            byte[] result = cipher.doFinal(Base64.decodeBase64(content));
            return new String(result, UTF_8);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static Cipher initCipher(String key, int encryptMode) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);

        SecretKeySpec keySpec = new SecretKeySpec(DigestUtils.sha1(key), AES_NAME);

        AlgorithmParameterSpec paramSpec = new IvParameterSpec(new byte[16]);
        cipher.init(encryptMode, keySpec, paramSpec);

        return cipher;
    }

    public static void main(String[] args) {
        String key = "123456";
        String encrpt = encrypt("hello", key);
        String src = decrypt(encrpt, key);
        System.out.println(encrpt);
        System.out.println(src);
    }
}
